#include<iostream>
#include<string>
#include"env_variables.cpp"
#include"history.cpp"
#include"hidden_process.cpp"
#include"Signal.cpp"
using namespace std;
static ShellRC shell;
string prev_dir;
class Internal {
		
	public:

	static string getCWD() {
		return get_current_dir_name();
	}

	static void cd(string s) {
		bool flag =false;
		if(s=="-" && prev_dir != "") {
			string temp=getCWD();
			s=prev_dir;
			prev_dir=temp;
			flag=true;
		} 	
		if(s=="" || s=="~") {
			s=getValue("HOME");
		}
 		if(Utility::startswith(s, "$")) {
			s = s.substr(1);		
			s = getValue(s);
		}
		prev_dir=getCWD();
		if(s!= "" && chdir(s.c_str()) == -1) {
			Utility::err_start();
			cerr<<"Error in change directory"<<endl;
			Utility::err_end();
		} 
		
	}
		
	static void pwd() {
		Utility::out_start();
		cout<<getCWD()<<endl;		
		Utility::out_end();
	}

	static void setValue(string key, string value) {
		shell.setValue(key, value);
	}

	static void setValue(Command command) {
		string temp;
		int i=0;
		string key, value;
		string s = command.getCommandWithArgs();
		s = getAfter(s, command.getCommand());
		stringstream ss(s);
		while(getline(ss, temp, '=')) {
			if(i==0) key = temp;
			else {
				value=temp;
				break;
			}
			i++;
		}
		if (key != "" && value != "") {
			setValue(key, value);
		}	
	}

	static string getValue(string key) {
		if(key != "") return shell.getValue(key);
	}
	
	static void echo(string key) {
		if(key != "") {
			string value=key;
			if(Utility::startswith(key, "$")) {
				value = getValue(key.substr(1));
			} 
			if(value!="") {
				Utility::out_start();
				cout<<value<<endl;
				Utility::out_end();
			}					
		}
	}
	
	static string getAfter(string s1, string s2) {
		return Utility::trim(s1.substr(s2.length()));
	}

	static void start_wait(int pid) {
		int status;
       		while (1) {
                	waitpid(pid,&status,0);
                	if(errno== ECHILD) {
                    		break;
                	}
                }
	}

	static void execute(Command command) {
		string c = command.getCommand();
		if(c == "pwd") {
			pwd();
		} else if (c == "cd") {
			cd(getAfter(command.getCommandWithArgs(), command.getCommand()));
		} else if(c== "export") {
			setValue(command);
		} else if(c=="echo") {
			echo(getAfter(command.getCommandWithArgs(), command.getCommand()));
		} else if (c=="fg") {
			if(command.getCommandWithArgs() == c) {
				start_wait(Hidden::getLatestRunning());
			} else {
				string str = getAfter(command.getCommandWithArgs(), command.getCommand());
				int num=-1;
				istringstream ( str ) >> num;
				if(num != -1) {
					start_wait(num);
				}
			}
		} else if(c=="history"){
			History::display();
		}
			
	} 

	static char ** tokenize(string str, char separator) {
		int n = sizeof(char *) * str.length();
		char **tokens = (char **) malloc(n);
		stringstream ss(str);
		string s;
		int i=0;
		while (getline(ss, s, separator)) {
			if(Utility::startswith(s,"$")) {
				s = s.substr(1);
				s = getValue(s);
			}
			tokens[i] = (char *) malloc(sizeof(char) * (s.length() + 1));
		 	strcpy(tokens[i],s.c_str());
			i++;
		}
		//while(i<n-1) {
		///	cout<<i<<endl;
			tokens[i] = NULL;
		//	i++;
		//}
		return tokens;
	}
};
	
